package com.example.cms.Queues;

import com.example.cms.DB.DBUtil;
import com.example.cms.Users.User;
import com.example.cms.Schedules.*;
import com.example.cms.Appointments.*;
import java.sql.*;
import java.sql.Date;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class QueuesManager {
    private Scanner scanner;
    private AppointmentsManager appointmentsManager;
    private SchedulesManager schedulesManager;
    private Schedule schedule;
    private Appointment appointment;
    private User currentUser;

    // 日期时间格式化器

    private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

    public QueuesManager() {
        this.scanner = new Scanner(System.in);
    }
    // ==================== 队列管理 ====================
    public void showQueueMenu() {
        while (true) {
            System.out.println("\n--- 队列管理 ---");
            System.out.println("1. 加入队列");
            System.out.println("2. 叫号");
            System.out.println("3. 完成就诊");
            System.out.println("4. 查看当前队列");
            System.out.println("0. 返回主菜单");

            System.out.print("请选择操作: ");
            String choice = scanner.nextLine();

            switch (choice) {
                case "1":
                    joinQueue();
                    break;
                case "2":
                    callNextPatient();
                    break;
                case "3":
                    finishConsultation();
                    break;
                case "4":
                    viewCurrentQueue();
                    break;
                case "0":
                    return;
                default:
                    System.out.println("无效选择，请重新输入！");
            }
        }
    }

    private void joinQueue() {
        System.out.println("\n--- 加入队列 ---");
        try {
            System.out.print("预约ID: ");
            int appointmentId = Integer.parseInt(scanner.nextLine());

            Appointment appointment = appointmentsManager.findAppointmentById(appointmentId);
            if (appointment == null) {
                System.out.println("预约不存在！");
                return;
            }

            Schedule schedule = schedulesManager.findScheduleById(appointment.getScheduleId());
            if (schedule == null) {
                System.out.println("排班信息不存在！");
                return;
            }

            // 生成队列号
            int queueNumber = getNextQueueNumber(schedule.getDoctorId());

            Queue queue = new Queue(appointmentId, schedule.getDoctorId(), queueNumber);
            queue.setPatientName(appointment.getPatientName());
            queue.setDoctorName(schedule.getDoctorName());
            queue.setDepartmentName(schedule.getDepartmentName());
            queue.setRoomNumber(schedule.getRoomNumber());

            if (addQueue(queue)) {
                // 更新预约状态
                appointmentsManager.updateAppointmentStatus(appointmentId, "IN_QUEUE");
                System.out.println("加入队列成功！队列号: " + queueNumber);
            } else {
                System.out.println("加入队列失败！");
            }
        } catch (Exception e) {
            System.out.println("加入队列失败: " + e.getMessage());
        }
    }

    private void callNextPatient() {
        System.out.println("\n--- 叫号 ---");
        try {
            System.out.print("医生ID: ");
            int doctorId = Integer.parseInt(scanner.nextLine());

            Queue currentQueue = getCurrentQueue(doctorId);
            if (currentQueue == null) {
                System.out.println("当前没有等待的患者！");
                return;
            }

            currentQueue.setQueueStatus("CALLED");
            if (updateQueue(currentQueue)) {
                System.out.println("请 " + currentQueue.getPatientName() + " 到诊室就诊！");
                System.out.println("队列号: " + currentQueue.getQueueNumber());
            } else {
                System.out.println("叫号失败！");
            }
        } catch (Exception e) {
            System.out.println("叫号失败: " + e.getMessage());
        }
    }

    private void finishConsultation() {
        System.out.println("\n--- 完成就诊 ---");
        try {
            System.out.print("队列ID: ");
            int queueId = Integer.parseInt(scanner.nextLine());

            Queue queue = findQueueById(queueId);
            if (queue == null) {
                System.out.println("队列记录不存在！");
                return;
            }

            (queue).setQueueStatus("FINISHED");
            (queue).calculateWaitingTime();

            if (updateQueue((Queue) queue)) {
                // 更新预约状态
                appointmentsManager.updateAppointmentStatus(queue.getAppointmentId(), "COMPLETED");
                System.out.println("就诊完成！");
                System.out.println("等待时间: " + queue.getWaitingTime() + " 分钟");
            } else {
                System.out.println("完成就诊操作失败！");
            }
        } catch (Exception e) {
            System.out.println("操作失败: " + e.getMessage());
        }
    }

    private void viewCurrentQueue() {
        System.out.println("\n--- 当前队列 ---");
        try {
            System.out.print("医生ID: ");
            int doctorId = Integer.parseInt(scanner.nextLine());

            List<Queue> queues = getCurrentQueuesByDoctor(doctorId);
            if (queues.isEmpty()) {
                System.out.println("当前没有等待的患者");
                return;
            }

            System.out.println("队列号\t患者姓名\t状态\t等待时间\t进入时间");
            System.out.println("------------------------------------------------");
            for (Queue queue : queues) {
                long waitingMinutes = java.time.Duration.between(queue.getEnterTime(), LocalDateTime.now()).toMinutes();
                System.out.printf("%d\t%s\t%s\t%d分钟\t%s\n",
                        queue.getQueueNumber(),
                        queue.getPatientName(),
                        queue.getQueueStatus(),
                        waitingMinutes,
                        queue.getEnterTime().format(dateTimeFormatter));
            }
        } catch (Exception e) {
            System.out.println("获取队列失败: " + e.getMessage());
        }
    }

    // 队列相关操作方法
    private boolean addQueue(Queue queue) {
        String sql = "INSERT INTO queues (appointment_id, doctor_id, queue_number, schedule_date, " +
                "queue_status) VALUES (?, ?, ?, ?, ?)";

        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
            pstmt.setInt(1, queue.getAppointmentId());
            pstmt.setInt(2, queue.getDoctorId());
            pstmt.setInt(3, queue.getQueueNumber());
            pstmt.setDate(4, Date.valueOf(schedule.getScheduleDate()));
            pstmt.setString(5, queue.getQueueStatus());

            int affectedRows = pstmt.executeUpdate();
            if (affectedRows > 0) {
                try (ResultSet rs = pstmt.getGeneratedKeys()) {
                    if (rs.next()) {
                        queue.setQueueId(rs.getInt(1));
                    }
                }
                return true;
            }
        } catch (SQLException e) {
            System.err.println("添加队列失败: " + e.getMessage());
        }
        return false;
    }

    private Queue findQueueById(int queueId) {
        String sql = "SELECT q.*, a.appointment_no, p.name as patient_name, d.name as doctor_name " +
                "FROM queues q " +
                "JOIN appointments a ON q.appointment_id = a.appointment_id " +
                "JOIN patients p ON a.patient_id = p.patient_id " +
                "JOIN doctors d ON q.doctor_id = d.doctor_id " +
                "WHERE q.queue_id = ?";

        try (   Connection conn = DBUtil.getConnection();
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, queueId);
            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    return mapResultSetToQueue(rs);
                }
            }
        } catch (SQLException e) {
            System.err.println("查询队列失败: " + e.getMessage());
        }
        return null;
    }

    private Queue getCurrentQueue(int doctorId) {
        String sql = "SELECT q.*, a.appointment_no, p.name as patient_name, d.name as doctor_name " +
                "FROM queues q " +
                "JOIN appointments a ON q.appointment_id = a.appointment_id " +
                "JOIN patients p ON a.patient_id = p.patient_id " +
                "JOIN doctors d ON q.doctor_id = d.doctor_id " +
                "WHERE q.doctor_id = ? AND q.queue_status = 'WAITING' " +
                "AND q.schedule_date = CURDATE() " +
                "ORDER BY q.queue_number LIMIT 1";

        try (   Connection conn = DBUtil.getConnection();
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, doctorId);
            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    return mapResultSetToQueue(rs);
                }
            }
        } catch (SQLException e) {
            System.err.println("获取当前队列失败: " + e.getMessage());
        }
        return null;
    }

    private boolean updateQueue(Queue queue) {
        String sql = "UPDATE queues SET appointment_id = ?, doctor_id = ?, queue_number = ?, " +
                "schedule_date = ?, queue_status = ?, call_time = ?, finish_time = ? WHERE queue_id = ?";

        try (   Connection conn = DBUtil.getConnection();
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, queue.getAppointmentId());
            pstmt.setInt(2, queue.getDoctorId());
            pstmt.setInt(3, queue.getQueueNumber());
            pstmt.setDate(4, Date.valueOf(schedule.getScheduleDate()));
            pstmt.setString(5, queue.getQueueStatus());
            pstmt.setTimestamp(6, queue.getCallTime() != null ?
                    Timestamp.valueOf(queue.getCallTime()) : null);
            pstmt.setTimestamp(7, queue.getFinishTime() != null ?
                    Timestamp.valueOf(queue.getFinishTime()) : null);
            pstmt.setInt(8, queue.getQueueId());

            return pstmt.executeUpdate() > 0;
        } catch (SQLException e) {
            System.err.println("更新队列失败: " + e.getMessage());
        }
        return false;
    }

    private List<Queue> getCurrentQueuesByDoctor(int doctorId) {
        List<Queue> queues = new ArrayList<>();
        String sql = "SELECT q.*, a.appointment_no, p.name as patient_name, d.name as doctor_name " +
                "FROM queues q " +
                "JOIN appointments a ON q.appointment_id = a.appointment_id " +
                "JOIN patients p ON a.patient_id = p.patient_id " +
                "JOIN doctors d ON q.doctor_id = d.doctor_id " +
                "WHERE q.doctor_id = ? AND q.schedule_date = CURDATE() " +
                "AND q.queue_status IN ('WAITING', 'CALLED') " +
                "ORDER BY q.queue_number";

        try (   Connection conn = DBUtil.getConnection();
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, doctorId);
            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    queues.add(mapResultSetToQueue(rs));
                }
            }
        } catch (SQLException e) {
            System.err.println("获取医生队列失败: " + e.getMessage());
        }
        return queues;
    }

    private int getNextQueueNumber(int doctorId) {
        String sql = "SELECT COALESCE(MAX(queue_number), 0) + 1 as next_number " +
                "FROM queues WHERE doctor_id = ? AND schedule_date = CURDATE()";

        try (   Connection conn = DBUtil.getConnection();
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, doctorId);
            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    return rs.getInt("next_number");
                }
            }
        } catch (SQLException e) {
            System.err.println("获取下一个队列号失败: " + e.getMessage());
        }
        return 1;
    }




    private Queue mapResultSetToQueue(ResultSet rs) throws SQLException {
        Queue queue = new Queue();
        queue.setQueueId(rs.getInt("queue_id"));
        queue.setAppointmentId(rs.getInt("appointment_id"));
        queue.setDoctorId(rs.getInt("doctor_id"));
        queue.setQueueNumber(rs.getInt("queue_number"));
        schedule.setScheduleDate(rs.getDate("schedule_date").toLocalDate());
        queue.setQueueStatus(rs.getString("queue_status"));
        queue.setEnterTime(rs.getTimestamp("enter_time") != null ?
                rs.getTimestamp("enter_time").toLocalDateTime() : null);
        queue.setCallTime(rs.getTimestamp("call_time") != null ?
                rs.getTimestamp("call_time").toLocalDateTime() : null);
        queue.setFinishTime(rs.getTimestamp("finish_time") != null ?
                rs.getTimestamp("finish_time").toLocalDateTime() : null);
        queue.setWaitingTime(rs.getInt("waiting_time"));
        queue.setRoomNumber(rs.getString("room_number"));
        // 额外信息
        appointment.setAppointmentNo(rs.getString("appointment_no"));
        queue.setPatientName(rs.getString("patient_name"));
        queue.setDoctorName(rs.getString("doctor_name"));
        return queue;
    }

    public void setAppointmentsManager(AppointmentsManager appointmentsManager) {
        this.appointmentsManager = appointmentsManager;
    }
    public void setSchedulesManager(SchedulesManager schedulesManager) {
        this.schedulesManager = schedulesManager;
    }
    public void setCurrentUser(User currentUser) {
        this.currentUser = currentUser;
    }

}
